<?php

/**
 * Route for executing an action on a work item.
 * 
 * The route only matches valid work item and action combinations. Parameters specified below are auto-detected by object type.
 * See route <code>wf_workflow_node_execute_action</code>.
 * 
 * Parameters
 * - sf_subject		wfWorkflowWorkItem|InteractiveExecutableWorkItem	Work item to execute action on
 * - action_id		string												Identifier of action to be executed
 *
 * @author Maximilian Lenkeit <dev@lenki.com>
 */
class WorkflowNodeActionRoute extends sfDoctrineRoute
{

  public function matchesUrl ($url, $context = array())
  {
    if (false === $parameters = parent::matchesUrl($url, $context))
    {
      return false;
    }
    
    // Get executable work item
    $node = RunTimeWorkflowNodeFactory::getInstance()->create(
        wfWorkflowWorkItemTable::getInstance()->find(array(
          'id' => $parameters['id'])));
    
    // Work item has to be interactive
    if (! $node instanceof RunTimeWorkflowNode)
    {
      return false;
    }
    
    // Work item has to have the action specified
    if (! $node->hasAction($parameters['action_id']))
    {
      return false;
    }
    
    return $parameters;
  }

  public function generate ($params, $context = array(), $absolute = false)
  {
    foreach ($params as $k => $v)
    {
      // Unescape value
      if ($v instanceof sfOutputEscaper)
      {
        $v = $v->getRawValue();
      }
      
      // Auto-detect subject from InteractiveExecutableWorkItem
      if ($v instanceof AbstractRunTimeWorkflowNodeAction)
      {
        unset($params[$k]);
        $params['sf_subject'] = $v->getNode()->getObject();
        $params['action_id'] = $v->getIdentifier();
      }
    }
    
    return parent::generate($params, $context, $absolute);
  }

  /**
   * @return string
   */
  public function getActionIdentifier ()
  {
    return $this->parameters['action_id'];
  }
}